package com.sihan.framework.etm.app.controller;

import com.framework.annotation.ParamParser;
import com.framework.exception.AuthException;
import com.framework.model.ApiResult;
import com.framework.mybatis.Condition;
import com.framework.util.WebUtils;
import com.framework.util.crypto.digest.MD5;
import com.framework.util.lang.RegexpUtils;
import com.sihan.framework.etm.app.service.AppLoginService;
import com.sihan.framework.etm.common.BizErrorHelper;
import com.sihan.framework.etm.common.BizErrorItemModel;
import com.sihan.framework.etm.common.BizErrorModel;
import com.sihan.framework.etm.common.BooleanResultModel;
import com.sihan.framework.etm.common.util.EtmWebUtil;
import com.sihan.framework.etm.common.util.ImgUtils;
import com.sihan.framework.etm.dto.*;
import com.sihan.framework.etm.entity.Org;
import com.sihan.framework.etm.entity.User;
import com.sihan.framework.etm.entity.baseData.ToolModel;
import com.sihan.framework.etm.entity.business.ToolBorrowDetail;
import com.sihan.framework.etm.entity.business.ToolException;
import com.sihan.framework.etm.enums.FormatImgPre;
import com.sihan.framework.etm.mapper.OrgMapper;
import com.sihan.framework.etm.mapper.business.ToolExceptionMapper;
import com.sihan.framework.etm.service.baseData.ToolService;
import com.sihan.framework.etm.service.business.BorrowService;
import com.sihan.framework.etm.vo.LoginVO;
import com.sihan.framework.etm.vo.UserVO;
import com.sihan.framework.etm.vo.business.DevicePdVO;
import com.sihan.framework.etm.vo.business.ToolQueryVO;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import java.util.List;
import java.util.Map;

@Api(tags = "APP用户个人管理")
@RestController
@RequestMapping("/v0/app")
public class AppLoginController {

    @Autowired
    private AppLoginService userService;

    @Autowired
    private ApplicationContext springContext;

    @Autowired
    private BorrowService borrowService;

    @Autowired
    private ToolService toolService;

    @Autowired
    private ToolExceptionMapper toolExceptionMapper;

    @Autowired
    private ImgUtils imgUtils;

    @Autowired
    private OrgMapper orgMapper;

    @ApiOperation("登录系统")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username", value = "用户名", dataType = "string", paramType = "form", required = true),
            @ApiImplicitParam(name = "password", value = "密码", dataType = "string", paramType = "form", required = true)
    })
    @PostMapping("/login")
    public ResponseEntity<?> login(@Valid @ParamParser AppLoginDTO dto, HttpServletRequest request) throws AuthException {
        Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession();
        String hashId = MD5.getInstance().encode(session.getId() + session.getHost() + request.getHeader("user-agent")).toHex();
        Object loginResult = userService.login(dto.getUsername(), dto.getPassword(), hashId);
        if (loginResult == BizErrorItemModel.LOGIN_ERROR_100001) {
            return new ResponseEntity<BizErrorModel>(BizErrorHelper.getBizErrorModel(springContext, BizErrorModel.LOGIN_ERROR,
                    BizErrorItemModel.LOGIN_ERROR_100001), HttpStatus.UNPROCESSABLE_ENTITY);
        } else if (loginResult == BizErrorItemModel.LOGIN_ERROR_100002) {
            return new ResponseEntity<BizErrorModel>(BizErrorHelper.getBizErrorModel(springContext, BizErrorModel.LOGIN_ERROR,
                    BizErrorItemModel.LOGIN_ERROR_100002), HttpStatus.PRECONDITION_FAILED);
        } else if (loginResult == BizErrorItemModel.LOGIN_ERROR_100003) {
            return new ResponseEntity<BizErrorModel>(BizErrorHelper.getBizErrorModel(springContext, BizErrorModel.LOGIN_ERROR,
                    BizErrorItemModel.LOGIN_ERROR_100003), HttpStatus.PRECONDITION_FAILED);
        } else if (loginResult == BizErrorItemModel.LOGIN_ERROR_100004) {
            return new ResponseEntity<BizErrorModel>(BizErrorHelper.getBizErrorModel(springContext, BizErrorModel.LOGIN_ERROR,
                    BizErrorItemModel.LOGIN_ERROR_100004), HttpStatus.PRECONDITION_FAILED);
        } else if (loginResult == BizErrorItemModel.LOGIN_ERROR_100005) {
            return new ResponseEntity<BizErrorModel>(BizErrorHelper.getBizErrorModel(springContext, BizErrorModel.LOGIN_ERROR,
                    BizErrorItemModel.LOGIN_ERROR_100005), HttpStatus.PRECONDITION_FAILED);
        } else if (loginResult == BizErrorItemModel.LOGIN_ERROR_100006) {
            return new ResponseEntity<BizErrorModel>(BizErrorHelper.getBizErrorModel(springContext, BizErrorModel.LOGIN_ERROR,
                    BizErrorItemModel.LOGIN_ERROR_100006), HttpStatus.LOCKED);
        } else if (loginResult == BizErrorItemModel.LOGIN_ERROR_100007) {
            return new ResponseEntity<BizErrorModel>(BizErrorHelper.getBizErrorModel(springContext, BizErrorModel.LOGIN_ERROR,
                    BizErrorItemModel.LOGIN_ERROR_100007), HttpStatus.PRECONDITION_FAILED);
        }
        return new ResponseEntity<ApiResult<LoginVO>>(ApiResult.success((LoginVO) loginResult), HttpStatus.OK);
    }

    @GetMapping("/logout")
    @ApiOperation(value = "[SSL]退出系统", notes = "退出系统", response = BooleanResultModel.class)
    @RequiresAuthentication
    public ResponseEntity<?> logout() {
        SecurityUtils.getSubject().logout();
        return new ResponseEntity<ApiResult<?>>(ApiResult.success(), HttpStatus.OK);
    }

    @ApiOperation(value = "[SSL]获取个人信息", notes = "获取个人信息", response = UserVO.class)
    @GetMapping("/user")
    @RequiresAuthentication
    public ResponseEntity<?> info() {
        User user = userService.selectOne(new Condition<>(new User(WebUtils.username(), false)));
        //  Set<String> roles = roleService.selectRolesByUsername(WebUtils.username());
        //  Set<String> permissions = permissionService.selectPermissionsByRoles(roles);
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        //   userVO.setPermissions(permissions);
//    Long userId = null;
//	if(!codeService.isAdmin()) {
//		userId = EtmWebUtil.userId();
//	}
        //userVO.setTaskNum(userService.getTaskNum(userId));
        if (!StringUtils.isBlank(userVO.getAvator())) {
            userVO.setAvator(imgUtils.formatImgPath(FormatImgPre.PRE_AVATOR.getValue() + userVO.getAvator()));
        }
        Org o = orgMapper.selectById(userVO.getOrgId());
        if (null != o) {
            userVO.setTeamName(o.getName());
        }

        return new ResponseEntity<ApiResult<UserVO>>(ApiResult.success(userVO), HttpStatus.OK);
    }

    @ApiOperation(value = "[SSL]修改密码", notes = "修改密码", response = BooleanResultModel.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "oldPassword", value = "原用户密码", dataType = "string", paramType = "form", required = true),
            @ApiImplicitParam(name = "newPassword", value = "新用户密码", dataType = "string", paramType = "form", required = true),
            @ApiImplicitParam(name = "suNewPassword", value = "确认密码", dataType = "string", paramType = "form", required = true)
    })
    @PostMapping("/user/password")
    public ResponseEntity<?> updatePassword(String oldPassword, String newPassword, String suNewPassword) {
//      String oldPsd = dto.getOldPassword();
//      String newPsd = dto.getNewPassword();
//      String suNewPsd = dto.getSuNewPassword();

        if (!RegexpUtils.isPassword(oldPassword) || !RegexpUtils.isPassword(newPassword) || !RegexpUtils.isPassword(suNewPassword)) {
            return new ResponseEntity<BizErrorModel>(BizErrorHelper.getBizErrorModel(springContext, BizErrorModel.USER_ERROR,
                    BizErrorItemModel.USER_ERROR_100008), HttpStatus.UNPROCESSABLE_ENTITY);
        } else {
            if (!newPassword.equals(suNewPassword)) {
                return new ResponseEntity<BizErrorModel>(BizErrorHelper.getBizErrorModel(springContext, BizErrorModel.USER_ERROR,
                        BizErrorItemModel.USER_ERROR_100011), HttpStatus.UNPROCESSABLE_ENTITY);
            }
            Object result = userService.updatePassword(oldPassword, newPassword);
            if (result == BizErrorItemModel.USER_ERROR_100009) {
                return new ResponseEntity<BizErrorModel>(BizErrorHelper.getBizErrorModel(springContext, BizErrorModel.USER_ERROR,
                        BizErrorItemModel.USER_ERROR_100009), HttpStatus.UNPROCESSABLE_ENTITY);
            } else if (result == BizErrorItemModel.USER_ERROR_100012) {
                return new ResponseEntity<BizErrorModel>(BizErrorHelper.getBizErrorModel(springContext, BizErrorModel.USER_ERROR,
                        BizErrorItemModel.USER_ERROR_100012), HttpStatus.UNPROCESSABLE_ENTITY);
            } else if (result == BizErrorItemModel.USER_ERROR_100013) {
                return new ResponseEntity<BizErrorModel>(BizErrorHelper.getBizErrorModel(springContext, BizErrorModel.USER_ERROR,
                        BizErrorItemModel.USER_ERROR_100013), HttpStatus.UNPROCESSABLE_ENTITY);
            }
            SecurityUtils.getSubject().logout();
            return new ResponseEntity<ApiResult<BooleanResultModel>>(ApiResult.success((BooleanResultModel) result), HttpStatus.OK);
        }
    }

    @GetMapping("/borrow/quantity")
    @ApiOperation("领用数量统计")
    public ResponseEntity<?> getBorrowQuantity() {
        Integer result = borrowService.getBorrowQuantity(EtmWebUtil.userId());
        return new ResponseEntity<ApiResult<Integer>>(ApiResult.success(result), HttpStatus.OK);
    }

    @GetMapping("/borrow/quantityEachType")
    @ApiOperation("各个类型领用数量统计")
    public ResponseEntity<?> getBorrowQuantityEachType() {
        List<Map<String, String>> result = borrowService.getBorrowQuantityEachType(EtmWebUtil.userId());
        return new ResponseEntity<ApiResult<List<Map<String, String>>>>(ApiResult.success(result), HttpStatus.OK);
    }

    @GetMapping("/borrow/rfidAndModel")
    @ApiOperation("领用工器具RFID编号和型号")
    public ResponseEntity<?> getBorrowRfidAndModel() {
        List<Map<String, String>> result = borrowService.getBorrowRfidAndModel(EtmWebUtil.userId());
        return new ResponseEntity<ApiResult<List<Map<String, String>>>>(ApiResult.success(result), HttpStatus.OK);
    }

    @GetMapping("/deviceScan/quantity")
    @ApiOperation("扫描数量统计")
    public ResponseEntity<?> getScanQuantity(@ApiParam(name = "rfids", value = "RFIDs", required = true) @RequestParam List<String> rfids) {
        Integer result = borrowService.getScanQuantity(rfids);
        return new ResponseEntity<ApiResult<Integer>>(ApiResult.success(result), HttpStatus.OK);
    }

    @GetMapping("/deviceScan/quantityEachType")
    @ApiOperation("各个类型扫描数量统计")
    public ResponseEntity<?> getScanQuantityEachType(@ApiParam(name = "rfids", value = "RFIDs", required = true) @RequestParam List<String> rfids) {
        List<Map<String, String>> result = borrowService.getScanQuantityEachType(rfids);
        return new ResponseEntity<ApiResult<List<Map<String, String>>>>(ApiResult.success(result), HttpStatus.OK);
    }

    @GetMapping("/deviceScan/rfidAndModel")
    @ApiOperation("rfid编号和型号列表")
    public ResponseEntity<?> getScanRfidAndModel(@ApiParam(name = "rfids", value = "RFIDs", required = true) @RequestParam List<String> rfids) {
        List<Map<String, String>> result = borrowService.getScanRfidAndModel(rfids);
        return new ResponseEntity<ApiResult<List<Map<String, String>>>>(ApiResult.success(result), HttpStatus.OK);
    }

    @GetMapping("/devicePd")
    @ApiOperation("设备盘点-领用扫描对比、缺失类型数量统计")
    public ResponseEntity<?> getDevicePdInfo(@ApiParam(name = "rfids", value = "RFIDs", required = true) @RequestParam List<String> rfids) {
        DevicePdVO result = borrowService.getDevicePdInfo(rfids, EtmWebUtil.userId());
        return new ResponseEntity<ApiResult<DevicePdVO>>(ApiResult.success(result), HttpStatus.OK);
    }

    @GetMapping("/deviceView/toolDetail")
    @ApiOperation("设备查看-工器具详情")
    public ResponseEntity<?> getToolDetail(@ApiParam(name = "rfid", value = "RFID", required = true) @RequestParam String rfid) {
        ToolQueryVO result = borrowService.getToolDetail(rfid);
        return new ResponseEntity<ApiResult<ToolQueryVO>>(ApiResult.success(result), HttpStatus.OK);
    }

    @SuppressWarnings("unchecked")
    @PostMapping("/deviceView/exceptionReport")
    @ApiOperation("设备查看-工器具异常上报")
    public ResponseEntity<?> exceptionReport(@ApiParam(name = "rfid", value = "RFID", required = true) @RequestParam String rfid) {
        ToolException toolException = new ToolException();
        ToolModel toolModel = toolService.selectOne(new Condition<ToolModel>().eq("code", rfid));
        if (null != toolModel) {
            toolException.setToolId(toolModel.getId());
            ToolBorrowDetail toolBorrowDetail = borrowService.getOutAndInDate(toolModel.getId());
            if (null != toolBorrowDetail) {
                toolException.setOutWarehouseTime(toolBorrowDetail.getCreateTime());
                if (toolBorrowDetail.getHasReturn() == 1) {
                    toolException.setIntWarehouseTime(toolBorrowDetail.getReturnTime());
                }
            }
            toolException.setOperatorUserId(EtmWebUtil.userId());
            toolExceptionMapper.saveOrUpdate(toolException);
            //borrowService.updateBorrowDetailStatus(toolBorrowDetail.getId());
            return new ResponseEntity<ApiResult<ToolException>>(ApiResult.success(toolException), HttpStatus.OK);
        }
        return new ResponseEntity<ApiResult<ToolException>>(ApiResult.fail("未查询到此工器具编号：" + rfid), HttpStatus.OK);
    }

    @GetMapping("/toolTypeList")
    @ApiOperation("查询工器具类型列表")
    public ResponseEntity<?> getToolTypeList() {
        List<Map<String, String>> result = borrowService.getToolTypeList();
        return new ResponseEntity<ApiResult<List<Map<String, String>>>>(ApiResult.success(result), HttpStatus.OK);
    }
}
